package zasm.zasm.listing;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.Iterator;

class DefaultTextListingWriter extends TextListingWriter {

	private static final char[]	PLUSES	= new char[MAX_COLUMN_WIDTH];

	static {
		Arrays.fill(PLUSES, '+');
	}

	private final int			lineNumberWidth;
	private final int			fileNestWidth;
	private final int			originIntWidth;
	private final int			originWidth;
	private final int			outWidth;

	protected DefaultTextListingWriter(final Writer writer, final int tabWidth, final boolean useSpaces,
			final int lineNumberWidth, final int fileNestWidth, final int originIntWidth, final int originWidth,
			final int outWidth) {
		super(writer, tabWidth, useSpaces);
		this.lineNumberWidth = lineNumberWidth;
		this.fileNestWidth = fileNestWidth;
		this.originIntWidth = originIntWidth;
		this.originWidth = originWidth;
		this.outWidth = outWidth;
	}

	protected DefaultTextListingWriter(final File file, final int tabWidth, final boolean useSpaces,
			final int lineNumberWidth, final int fileNestWidth, final int originIntWidth, final int originWidth,
			final int outWidth) throws FileNotFoundException {
		super(file, tabWidth, useSpaces);
		this.lineNumberWidth = lineNumberWidth;
		this.fileNestWidth = fileNestWidth;
		this.originIntWidth = originIntWidth;
		this.originWidth = originWidth;
		this.outWidth = outWidth;
	}

	protected DefaultTextListingWriter(final String fileName, final int tabWidth, final boolean useSpaces,
			final int lineNumberWidth, final int fileNestWidth, final int originIntWidth, final int originWidth,
			final int outWidth) throws FileNotFoundException {
		super(fileName, tabWidth, useSpaces);
		this.lineNumberWidth = lineNumberWidth;
		this.fileNestWidth = fileNestWidth;
		this.originIntWidth = originIntWidth;
		this.originWidth = originWidth;
		this.outWidth = outWidth;
	}

	@Override
	public void writeInternal(final Iterator<String> in, final byte[] out) throws IOException {
		writeDecInt(getLineNumber(), lineNumberWidth);
		write(PLUSES, 0, getFileDepth() - 1);
		setColumn(lineNumberWidth + fileNestWidth);

		writeHexInt(getOrigin(), originIntWidth);

		int outIndex = 0;

		while ((outIndex < out.length) || (in.hasNext())) {
			setColumn(lineNumberWidth + originWidth);

			if (outIndex < out.length) {
				writeHexInt(out[outIndex++], 2);

				for (int nextOutWidth = 2 + 3 + 1; nextOutWidth < outWidth; nextOutWidth += 3) {
					write(' ');
					writeHexInt(out[outIndex++], 2);
				}
			}

			if (in.hasNext()) {
				write(in.next());
			}

			writeln();
		}
	}

}
